package com.tuling.aspect;

import com.tuling.annotation.RepeatSubmit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

//@Aspect
//@Component
public class RepeatSubmitAspect {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Pointcut(value = "@annotation(com.tuling.annotation.RepeatSubmit)")
    public void pointCutRepeatSubmit(RepeatSubmit repeatSubmit){

    }
    @Around(value = "pointCutRepeatSubmit(repeatSubmit)",argNames ="proceedingJoinPoint,repeatSubmit" )
    public Object repeatSubmit(ProceedingJoinPoint proceedingJoinPoint,RepeatSubmit repeatSubmit){
        //获取到
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String key = ":repeat_submit:";
        String url = request.getRequestURI();
        String ipAddr = request.getRemoteAddr();
        String type = repeatSubmit.limitType().name();
        if(type.equals(RepeatSubmit.Type.PARAM.name())){
            MethodSignature signature = (MethodSignature)proceedingJoinPoint.getSignature();
            Method method = signature.getMethod();
            String name = method.getDeclaringClass().getName();
            key = key + String.format("-%s-%s-%s-%s",ipAddr,url,name,method);

        }else{
            String token = request.getHeader("token");
            if(!StringUtils.hasText(token)){
                return "token 不存在";
            }

            key = key + String.format("-%s-%s",token,url);
        }

        key = DigestUtils.md5DigestAsHex(key.getBytes(StandardCharsets.UTF_8));

        if(Boolean.FALSE.equals(stringRedisTemplate.hasKey(key))){
//            stringRedisTemplate.opsForHash(key,"",repeatSubmit.lockTime(), TimeUnit.SECONDS)
            stringRedisTemplate.opsForHash().putIfAbsent(key,repeatSubmit.lockTime(),TimeUnit.SECONDS);
            try {
               return proceedingJoinPoint.proceed();
            }catch (Throwable e){
                stringRedisTemplate.delete(key);
                return  "请勿重复提交";
            }
        }else{
           return  "请勿重复提交";
        }
    }

}

